package com.opennice;
import java.io.File;
import java.io.IOException;
 
import net.paoding.analysis.analyzer.PaodingAnalyzer;
 
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Formatter;
import org.apache.lucene.search.highlight.Fragmenter;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
 
 
/**
 * lucene3.2+paoding的例子
 * @author sunlightcs
 * 2011-6-19
 * http://hi.juziku.com/sunlightcs/
 */
public class TestPaoding {
    //索引文件位置
     File dataFile = new File("D://indexFile");
    //使用庖丁分词器
    Analyzer analyzer = new PaodingAnalyzer();
     
    //使用IK分词器，要导入IK分词器的JAR包，最新版本是3.2.8
    //Analyzer analyzer = new IKAnalyzer();
     
    public static void main(String[] args) {
        new TestPaoding().bulidIndex();
        new TestPaoding().search("越南向联合国大陆架界限委员会单独提交了南海");
    }
     
    /**
     * 建立新的索引数据
     */
    public void bulidIndex(){
        Directory directory = null;
        IndexWriter writer = null;
        try {
             
            directory = FSDirectory.open(dataFile);
             
            IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_32, analyzer);
            writer = new IndexWriter(directory, writerConfig);
             
             
            addIndexDocument(writer, 12, "越南向联合国大陆架界限委员会单独提交了南海“外大陆架划界案”，声称有3260公里长的海岸线并对" +
                    "中国的西沙和南沙群岛享有主权。中国外交部发言人马朝旭在北京表示，越南提交的所谓“外大陆架划界案”，严重侵犯了中国的" +
                    "主权、主权权利和管辖权，是非法的、无效的");
             
        }catch(Exception ex){
            ex.printStackTrace();
        } finally {
            try {
                writer.optimize();
                writer.close();
                directory.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
         
    }
     
     
    /**
     * 添加到document中
     */
    public void addIndexDocument(IndexWriter writer, Integer id, String content) { 
        try {
            Document doc = new Document();
             
            /**
             * Field.Index.NO 表示不索引
             * Field.Index.ANALYZED 表示分词且索引
             * Field.Index.NOT_ANALYZED 表示不分词且索引
             */
            doc.add(new Field("id", String.valueOf(id), Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED));
            System.out.println(doc);
            writer.addDocument(doc);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
     
     
    /**
     * 更新索引
     */
    public void update(Integer id, String content) {
         
        try {          
            Directory directory = FSDirectory.open(dataFile);
             
            IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_32, analyzer);
            IndexWriter writer = new IndexWriter(directory, writerConfig);
             
            Document doc = new Document();         
            doc.add(new Field("id", String.valueOf(id), Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED));
             
            Term term = new Term("id", String.valueOf(id));
             
            writer.updateDocument(term, doc);
             
            directory.close();
            writer.close();
             
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     
     
    /**
     * 删除索引
     */
    public void delete(Integer id) {
        try {
            Directory directory = FSDirectory.open(dataFile);
             
            IndexWriterConfig writerConfig = new IndexWriterConfig(Version.LUCENE_32, analyzer);
            IndexWriter writer = new IndexWriter(directory, writerConfig);
             
            Term term = new Term("id", String.valueOf(id));
             
            writer.deleteDocuments(term);
             
            directory.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
     
     
    /**
     * 搜索
     * @param keyword
     */
    public void search(String keyword) {
        IndexSearcher isearcher = null;
        Directory directory = null;
        try {
            directory = FSDirectory.open(dataFile);
             
            /**
             * 创建索引搜索器 且只读
             */
            isearcher = new IndexSearcher(directory,true);
             
 
            QueryParser parser = new QueryParser(Version.LUCENE_32, "content", analyzer);
            Query query = parser.parse(keyword);
         
            /**
             *  执行搜索，获取查询结果集对象
             */
            TopDocs topDocs = isearcher.search(query,1000);
             
             
             
            ScoreDoc[] hits = topDocs.scoreDocs;
             
            /**
             * 关键字 高亮
             */
            Formatter formatter = new SimpleHTMLFormatter("<font color='red'>", "</font>");
            Scorer scorer = new QueryScorer(query);
            Highlighter highlighter = new Highlighter(formatter, scorer);
 
            /**
             * 设置摘取字符的长度，默认为100个字符
             */
            Fragmenter fragmenter = new SimpleFragmenter(100);
            highlighter.setTextFragmenter(fragmenter);
             
             
             
            for(ScoreDoc scoreDoc : hits){
                Document hitDoc = isearcher.doc(scoreDoc.doc);
                 
                String id = hitDoc.get("id");
                String content = highlighter.getBestFragment(analyzer, "content", hitDoc.get("content"));
                 
                System.out.println("id:" + id + "\n\rcontent:" + content);
            }
             
             
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                isearcher.close();
                directory.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
         
    }
}